  // CheckersBoard Engine API - Native Code Layer
 // Refactored from Martin Fierz's Checkers Board Front-End Application
////////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

 // Engine DLL pointer types
/////////////////////////////////////////////////////////////////////////////////////////

#define ENGINECOMMAND_REPLY_SIZE 1024

// board representations
#define FREE 0
#define WHITE 1
#define BLACK 2
#define CHANGECOLOR 3
#define MAN 4
#define KING 8

struct coor 				/* coordinate structure for board coordinates */
{
	// was ints
	int x;
	int y;
};


struct CBmove					/* all the information you need about a move */
{
	// was all ints. made char because i save CBmoves in user book - this saves
	// me a factor 4 - still, they are much too larg of course...
	int jumps;				/* how many jumps are there in this move? */
	int newpiece;			/* what type of piece appears on to */
	int oldpiece;			/* what disappears on from */
	struct coor from,to; /* coordinates of the piece - in 8x8 notation!*/
	struct coor path[12];/* intermediate path coordinates of the moving piece */
	struct coor del[12]; /* squares whose pieces are deleted after the move */
	int delpiece[12]; 	/* what is on these squares */
};

// basic engine  options
#define FLAG_HASH_SIZE			1
#define FLAG_EGTB_SIZE			2
#define FLAG_BOOK				4
#define FLAG_ALL_SCORES			8

// enhanced engine options
#define FLAG_MAX_DB_PIECES		1
#define FLAG_WDL_DIR			2
#define FLAG_MTC_DIR			4
#define FLAG_BOOK_FILE			8
#define FLAG_ENABLE_WDL			16
#define FLAG_ENABLE_MTC			32
#define FLAG_SEARCH_THREADS		64

typedef struct
{
	unsigned int flags;		// supported settings
	int db_MB;				// EGTB mem
	int hash_MB;			// hash mem
	int book;				// opening book
	int allscores;			// 
} ENGINE_OPTIONS;

typedef struct  {
	unsigned int flags;
	int max_dbpieces;			/* limits the maximum number of pieces to use in egdb init/lookups. */
	int wld_egdb_enable;
	char wld_directory[MAX_PATH];
	int mtc_egdb_enable;
	char mtc_directory[MAX_PATH];
	char book_filename[MAX_PATH];
	int search_threads;
} MORE_ENGINE_OPTIONS;


typedef INT (WINAPI* PROC1)(int *board, int color, double maxtime, char str[1024], int *playnow, int info, int unused, struct CBmove *move);
typedef INT (WINAPI* PROC3)(char str[255]);/* engine name, engine help */
typedef unsigned int (WINAPI* PROC4)(void);	  /* gametype*/
typedef INT (WINAPI* PROC6)(int *board, int color, int from, int to, struct CBmove *move);/* islegal*/
typedef INT (WINAPI* COMMANDPROC)(char command[256], char reply[ENGINECOMMAND_REPLY_SIZE]); //enginecommand


  // global variables in the CheckersBoard front-end application are put into this struct
 // to allow multiple CB engines to run at the same time
/////////////////////////////////////////////////////////////////////////////////////////////////////
struct CB_APIStruct
{
public:
	bool enginebusy;		
	bool enginestarting;
	CRITICAL_SECTION engine_criticalsection;

	// settings variables
	int togglebook; // TO-DO: complete toggling the book on and off for the engine
	char engineOutput[1024];
	int playNow;
	int abortEngine;


	// engine DLL function pointers
	HMODULE hModule;
	PROC1 getmove;
	COMMANDPROC enginecommand;
	PROC6 islegal;
	PROC3 enginename;
	// PROC4 gametype; - what is it good for?
};

#define MAX_INIT_ERROR 1024


 // initialization / destruction
//////////////////////////////////////////////////////

void InitCB_API(CB_APIStruct *s);

CB_APIStruct* InitializeCBEngine(wchar_t* engineFilePath, wchar_t* szError);
void DestroyCBEngine(CB_APIStruct* s);


 // Engine methods
//////////////////////////////////////////////////////

int set_more_engine_options(CB_APIStruct *s, MORE_ENGINE_OPTIONS *options);
int get_more_engine_options(CB_APIStruct *s, MORE_ENGINE_OPTIONS *options);
int getengineoptions(CB_APIStruct* s, ENGINE_OPTIONS *options);
int setengineoptions(CB_APIStruct *s, ENGINE_OPTIONS *options);

int getMove(CB_APIStruct* s, int* board, int color, double maxtime, CBmove* move);
int isLegal(CB_APIStruct *s,  int color, int* board, int from, int to, CBmove* move);
int enginecommand(CB_APIStruct* s, char command[256], char reply[ENGINECOMMAND_REPLY_SIZE]);
int enginename(CB_APIStruct* s, char Lstr[256]);
int gametype(CB_APIStruct* s);
void abortengine(CB_APIStruct *s);


 // Synchronization functions
//////////////////////////////////////////////////////

int setenginestarting(CB_APIStruct* s, int value);
int setenginebusy(CB_APIStruct* s, int value);
int getenginestarting(CB_APIStruct* s);
int getenginebusy(CB_APIStruct* s);
